#!/run/current-system/profile/bin/guile \
-e main -s
!#

(add-to-load-path (dirname (current-filename)))

(use-modules (ice-9 getopt-long)
             (ice-9 textual-ports) ;;open-output-file
             (encrypt))

(define shift 1)
(define (set-shift amount)
  (let ((amount (string->number amount)))
    (if (not amount) ;; Only execute if the amount is a number.
        #f
        (let ((amount (abs amount)))
          (if (>= amount 26)
              (set! shift (modulo amount 26))
              (set! shift amount))))))

;; loop through each character in the file, and output the encrypted file
(define (caesar)
  (let ((char (get-char (current-input-port))))
    (when (not (eof-object? char))
      (if (char-alphabetic? char)
          (put-char (current-output-port)
                    (encrypt shift char))
          (put-char (current-output-port) char))
      (caesar))))

(define (main args)
  ;;the option specification tells getopt-long how
  ;; to parse the command line
  (let* ((option-spec `((version (single-char #\v) (value #f))
                        (help    (single-char #\h) (value #f))
                        (file    (single-char #\f) (value #t)
                                 (predicate ,file-exists?))
                        (shift   (single-char #\s) (value #t)
                                 (predicate ,set-shift))))
         (program-name "caesar")
         ;; tell getopt-long to parse the command line and put
         ;; the data in options
         (options (getopt-long args option-spec))
         (help-wanted    (option-ref options 'help #f))
         (version-wanted (option-ref options 'version #f))
         (file-wanted    (option-ref options 'file #f))
         (shift-wanted   (option-ref options 'shift #f)))
    (if (or help-wanted version-wanted file-wanted)
        (cond
         (version-wanted (print-version program-name))
         (help-wanted (print-help program-name))
         (file-wanted
          (with-input-from-file file-wanted caesar))))))
